﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FrameWork.Source.Object_Classes;
using FrameWork.Source.Animation_Classes;
using FrameWork.Source.Texture;
using FrameWork.Source.Resource_Manager;
using Boomer.Source.TiledMap;
using Microsoft.Xna.Framework;
using Boomer.Source.Breakable_Object;

namespace Boomer.Source.Boom
{
    class CFragment : CAnimatedObject
    {
        private enum FLIP
        {
            LEFT , 
            RIGHT , 
            UP ,
            DOWN
        }

        private CTiledMap map;
        private float timeLife;
        private float maxTimeLife;
        private int strenght;
        private bool isDying;
        private Vector2 centerPos;
        private List<Vector2> listPos;
        private List<Vector2> listPosHead;
        private CAnimatedObject headAnim;
        private CAnimatedObject bodyAnim;
        private List<Vector2> listMapBodyPos;
        private List<Vector2> listMapHeadPos;
        private Vector2 centerMapPos;

        public CFragment()
            : base()
        {
            this.Tag = FrameWork.Tag_Manager.TagManager.TAGGED.Boom;
            this.m_isAlive = false;
        }

        public override void init()
        {
            CAnimation[] pCenterAnim;
            pCenterAnim = new CAnimation[2];

            pCenterAnim[0] = new CAnimation();
            pCenterAnim[0].createAnimation("Center Fragment", 0, 0, 0, 1.0f);

            pCenterAnim[1] = new CAnimation();
            pCenterAnim[1].createAnimation("Center Fragment Explor", 0, 3, 3, 1.0f / 50.0f);

            CAnimation[] pHeadAnim;
            pHeadAnim = new CAnimation[2];

            pHeadAnim[0] = new CAnimation();
            pHeadAnim[0].createAnimation("Head Fragment", 4, 4, 4, 1.0f);

            pHeadAnim[1] = new CAnimation();
            pHeadAnim[1].createAnimation("Head Fragment Explor", 9, 17, 17, 1.0f / 50.0f);

            CAnimation pBodyAnim = new CAnimation();
            pBodyAnim.createAnimation("Body Fragment", 8, 8, 8, 1.0f);


            CTexture image = CResourceManager.getInstance().getImage((int)CResourceManager.IMG_MAIN.FRAGMENT);

            loadSprite(image, 18, 4, 50, 50, pCenterAnim);

            headAnim = new CAnimatedObject();
            headAnim.loadSprite(image, 18, 4, 50, 50, pHeadAnim);

            bodyAnim = new CAnimatedObject();
            bodyAnim.loadSprite(image, 18, 4, 50, 50, pBodyAnim);

            getSprite().setCenterOrigin(m_iFrameWidth, m_iFrameHeight);
            headAnim.getSprite().setCenterOrigin(m_iFrameWidth, m_iFrameHeight);
            bodyAnim.getSprite().setCenterOrigin(m_iFrameWidth, m_iFrameHeight);

            timeLife = 0.0f;
            maxTimeLife = 0.05f;
            strenght = 0;
            isDying = false;
            map = new CTiledMap();
            centerPos = new Vector2();
            listPos = new List<Vector2>();
            listPosHead = new List<Vector2>();
            listMapHeadPos = new List<Vector2>();
            listMapBodyPos = new List<Vector2>();
            centerMapPos = new Vector2();

            base.init();
        }

        public void explorsion(Vector2 pos , int strenght , CTiledMap map)
        {
            this.centerPos = pos;
            this.strenght = strenght;
            this.map = map;

            listPos.Clear();
            listPosHead.Clear();
            listMapHeadPos.Clear();
            listMapBodyPos.Clear();

            bool isLeft = true;
            bool isRight = true;
            bool isTop = true;
            bool isBot = true;

            Vector2 mapPos = new Vector2();

            for (int i = 0; i < strenght; ++i)
            {
                if (isLeft)
                {
                    Vector2 left = new Vector2(centerPos.X - 50 * (i + 1), centerPos.Y);
                    mapPos = map.convertToMapIndex(left);
                    if (mapPos.Y < 0)
                    {
                        isLeft = false;
                    }
                    else
                    {
                        int mapIndex = map.getCell((int)mapPos.X, (int)mapPos.Y);
                        if (mapIndex == (int)CTiledMap.MAP_TYPE.BOOM)
                        {
                            BoomManager.getInstance().activeBoom(mapPos);
                        }
                        else if (mapIndex >= (int)CTiledMap.MAP_TYPE.BREAK_BOX_RED)
                        {
                            ObjectManager.getInstance().breaking(mapPos);
                            isLeft = false;
                        }
                        else if (mapIndex != 0 && mapIndex < (int)CTiledMap.MAP_TYPE.COUNT)
                        {
                            isLeft = false;
                        }
                        else
                        {
                            if (i == strenght - 1)
                                listPosHead.Add(left);
                            else
                                listPos.Add(left);
                        }
                    }

                }
                if( isRight )
                {
                    Vector2 right = new Vector2(centerPos.X + 50 * (i + 1), centerPos.Y);
                    mapPos = map.convertToMapIndex(right);
                    if( mapPos.Y >= map.m_iMapWidth )
                    {
                        isRight = false;
                    }
                    else
                    {
                        int mapIndex = map.getCell((int)mapPos.X, (int)mapPos.Y);
                        if (mapIndex == (int)CTiledMap.MAP_TYPE.BOOM)
                        {
                            BoomManager.getInstance().activeBoom(mapPos);
                        }
                        else if (mapIndex >= (int)CTiledMap.MAP_TYPE.BREAK_BOX_RED)
                        {
                            ObjectManager.getInstance().breaking(mapPos);
                            isRight = false;
                        }
                        else if (mapIndex != 0 && mapIndex < (int)CTiledMap.MAP_TYPE.COUNT)
                        {
                            isRight = false;
                        }
                        else
                        {
                            if (i == strenght - 1)
                                listPosHead.Add(right);
                            else
                                listPos.Add(right);
                        }
                    }
                }
                if( isTop )
                {
                    Vector2 top = new Vector2(centerPos.X, centerPos.Y - 50 * (i + 1));
                    mapPos = map.convertToMapIndex(top);
                    if( mapPos.X < 0 )
                    {
                        isTop = false;
                    }
                    else 
                    {
                        int mapIndex = map.getCell((int)mapPos.X, (int)mapPos.Y);
                        if (mapIndex == (int)CTiledMap.MAP_TYPE.BOOM)
                        {
                            BoomManager.getInstance().activeBoom(mapPos);
                        }
                        else if (mapIndex >= (int)CTiledMap.MAP_TYPE.BREAK_BOX_RED)
                        {
                            ObjectManager.getInstance().breaking(mapPos);
                            isTop = false;
                        }
                        else if (mapIndex != 0 && mapIndex < (int)CTiledMap.MAP_TYPE.COUNT)
                        {
                            isTop = false;
                        }
                        else
                        {
                            if (i == strenght - 1)
                                listPosHead.Add(top);
                            else
                                listPos.Add(top);
                        }
                    }
                }
                if (isBot)
                {
                    Vector2 bot = new Vector2(centerPos.X, centerPos.Y + 50 * (i + 1));
                    mapPos = map.convertToMapIndex(bot);
                    if (mapPos.X >= map.m_iMapHeight)
                    {
                        isBot = false;
                    }
                    else 
                    {
                        int mapIndex = map.getCell((int)mapPos.X, (int)mapPos.Y);
                        if (mapIndex == (int)CTiledMap.MAP_TYPE.BOOM)
                        {
                            BoomManager.getInstance().activeBoom(mapPos);
                        }
                        else if (mapIndex >= (int)CTiledMap.MAP_TYPE.BREAK_BOX_RED)
                        {
                            ObjectManager.getInstance().breaking(mapPos);
                            isBot = false;
                        }
                        else if (mapIndex != 0 && mapIndex < (int)CTiledMap.MAP_TYPE.COUNT)
                        {
                            isBot = false;
                        }
                        else
                        {
                            if (i == strenght - 1)
                                listPosHead.Add(bot);
                            else
                                listPos.Add(bot);
                        }
                    }
                }
            }

            headAnim.changeAnimation("Head Fragment");
            this.changeAnimation("Center Fragment");

            centerMapPos = map.convertToMapIndex(centerPos);
            map.setCell((int)centerMapPos.X, (int)centerMapPos.Y, (int)CTiledMap.MAP_TYPE.BOOM_FRAGMENT);

            int sizeHead = listPosHead.Count;
            int sizeBody = listPos.Count;
            Vector2 headMapPos = new Vector2();
            Vector2 bodyMapPos = new Vector2();
            int j;

            for (j = 0; j < sizeHead; ++j)
            {
                headMapPos = map.convertToMapIndex(listPosHead[j]);
                map.setCell((int)headMapPos.X, (int)headMapPos.Y, (int)CTiledMap.MAP_TYPE.BOOM_FRAGMENT );
                listMapHeadPos.Add(headMapPos);
            }

            for( j = 0 ; j < sizeBody ; ++j )
            {
                bodyMapPos = map.convertToMapIndex(listPos[j] );
                map.setCell( (int)bodyMapPos.X , (int)bodyMapPos.Y , (int)CTiledMap.MAP_TYPE.BOOM_FRAGMENT );
                listMapBodyPos.Add(bodyMapPos);
            }

            m_isAlive = true;
        }

        private void flip(CAnimatedObject objectToFlip  , FLIP flip)
        {
            if (flip == FLIP.LEFT)
            {
                objectToFlip.getSprite().m_fAngle = 0;
            }
            if (flip == FLIP.RIGHT)
            {
                objectToFlip.getSprite().m_fAngle = 180;
            }
            if (flip == FLIP.UP)
            {
                objectToFlip.getSprite().m_fAngle = 90;
            }
            if (flip == FLIP.DOWN)
            {
                objectToFlip.getSprite().m_fAngle = -90;
            }
        }

        public override void update(float deltaTime)
        {
            if (m_isAlive)
            {
                if (!isDying)
                {
                    timeLife += deltaTime;
                    if (timeLife >= maxTimeLife)
                    {
                        timeLife = 0;
                        headAnim.changeAnimation("Head Fragment Explor");
                        headAnim.getCurrAnimation().resetAnimation();
                        this.changeAnimation("Center Fragment Explor");
                        this.getCurrAnimation().resetAnimation();
                        isDying = true;
                    }
                }
                else
                {
                    if (headAnim.getCurrAnimation().isEndAnimation() && this.getCurrAnimation().isEndAnimation())
                    {
                        isDying = false;
                        m_isAlive = false;

                        map.setCell((int)centerMapPos.X, (int)centerMapPos.Y, (int)CTiledMap.MAP_TYPE.GRASS);

                        int sizeHead = listMapHeadPos.Count;
                        int sizeBody = listMapBodyPos.Count;
                        int j;

                        for (j = 0; j < sizeHead; ++j)
                        {
                            map.setCell((int)listMapHeadPos[j].X, (int)listMapHeadPos[j].Y, (int)CTiledMap.MAP_TYPE.GRASS);
                        }

                        for (j = 0; j < sizeBody; ++j)
                        {
                            map.setCell((int)listMapBodyPos[j].X, (int)listMapBodyPos[j].Y, (int)CTiledMap.MAP_TYPE.GRASS);
                        }
                    }
                }
                CTiledMap.updateDeep updateDeep = new CTiledMap.updateDeep(CTiledMap.updateDeepValue);

                this.m_fDeep = updateDeep(this.m_vec2Position, map);
                this.m_fDeep -= 0.03f;
                base.update(deltaTime);

                headAnim.m_fDeep = this.m_fDeep;
                headAnim.update(deltaTime);

                bodyAnim.m_fDeep = this.m_fDeep;
                bodyAnim.update(deltaTime);
            }
        }

        public override void draw()
        {
            if (m_isAlive)
            {
                int headCount = listPosHead.Count;

                int i;

                
                for (i = 0; i < headCount; ++i)
                {
                    headAnim.m_vec2Position = listPosHead[i];
                    if (headAnim.m_vec2Position.X > centerPos.X)
                        flip(headAnim, FLIP.RIGHT);
                    else if (headAnim.m_vec2Position.X < centerPos.X)
                        flip(headAnim, FLIP.LEFT);

                    if (headAnim.m_vec2Position.Y > centerPos.Y)
                        flip(headAnim , FLIP.DOWN);
                    else if (headAnim.m_vec2Position.Y < centerPos.Y)
                        flip(headAnim , FLIP.UP);

                    headAnim.m_vec2Position = new Vector2(listPosHead[i].X + headAnim.getSprite().m_vecOrigin.X, listPosHead[i].Y + headAnim.getSprite().m_vecOrigin.Y);
                    headAnim.draw();
                }

                int bodyCount = listPos.Count;

                for (i = 0; i < bodyCount; ++i)
                {
                    bodyAnim.m_vec2Position = listPos[i];
                    if (bodyAnim.m_vec2Position.X > centerPos.X)
                        flip(bodyAnim , FLIP.RIGHT);
                    else if (bodyAnim.m_vec2Position.X < centerPos.X)
                        flip(bodyAnim , FLIP.LEFT);

                    if (bodyAnim.m_vec2Position.Y > centerPos.Y)
                        flip(bodyAnim , FLIP.DOWN);
                    else if (bodyAnim.m_vec2Position.Y < centerPos.Y)
                        flip(bodyAnim , FLIP.UP);

                    bodyAnim.m_vec2Position = new Vector2(listPos[i].X + bodyAnim.getSprite().m_vecOrigin.X, listPos[i].Y + bodyAnim.getSprite().m_vecOrigin.Y);
                    bodyAnim.draw();
                }

                
                m_vec2Position = new Vector2(centerPos.X + getSprite().m_vecOrigin.X, centerPos.Y + getSprite().m_vecOrigin.Y);
                base.draw();
            }
        }

        public override bool Collision(ref CObject pObj)
        {
            return base.Collision(ref pObj);
        }
    }
}
